import logger from '../core/logger';
import apiProvider from './core/apiProvider';
import { clientBase } from './core/clientBase';
import returnModel from '../model/common/returnModel';
import { emptyData } from '../model/common/emptyData';
import searchLiveRoomItem from '../model/search/searchLiveRoomItem';
import searchAnimeItem from '../model/search/searchAnimeItem';
import searchVideoItem from '../model/search/searchVideoItem';
import searchUserItem from '../model/search/searchUserItem';
import searchArticleItem from '../model/search/searchArticleItem';
import searchTopicItem from '../model/search/searchTopicItem';

class searchClient extends clientBase {
  constructor() {
    super();
  }

  getLives(keywords: string, index?: number): Promise<returnModel<searchLiveRoomItem[]>> {
    return new Promise((resolve) => {
      let url;
      if (index)
        url = `https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=live&cover_type=user_cover&page=${index}&keyword=${keywords}&__refresh__=true&changing=mid&highlight=1&single_column=0`;
      else
        url = `https://api.bilibili.com/x/web-interface/search/type?search_type=live&platform=pc&keyword=${keywords}&page=1`;
      this.client.getResult(url).then((res) => {
        try {
          if (res.code == 0) {
            let arr: Array<searchLiveRoomItem> = res.data.data.result.live_room;
            resolve(this.buildSuccessResult<searchLiveRoomItem[]>(arr));
          } else
            resolve(this.buildFailedResult<searchLiveRoomItem[]>(res.message));
        } catch (e) {
          logger.error(e);
          resolve(this.buildExceptionResult<searchLiveRoomItem[]>(e));
        }
      });
    });
  }

  getUser(keywords: string, index: number): Promise<returnModel<emptyData>> {
    return new Promise((resolve) => {
      let url = `https://api.bilibili.com/x/web-interface/search/type?search_type=live_user&platform=pc&keyword=${keywords}&page=${index}&order=online&coverType=user_cover`;
      this.client.getResult(url).then((res) => {
        try {
          if (res.code == 0) {
            let data: emptyData = res.data;
            resolve(this.buildSuccessResult<emptyData>(data));
          } else
            resolve(this.buildFailedResult<emptyData>(res.message));
        } catch (e) {
          logger.error(e);
          resolve(this.buildExceptionResult<emptyData>(e));
        }
      });
    });
  }

  getLiving(keywords: string, index: number): Promise<returnModel<emptyData>> {
    return new Promise((resolve) => {
      let url = `https://api.bilibili.com/x/web-interface/search/type?search_type=live&platform=pc&keyword=${keywords}&page=${index}`;
      this.client.getResult(url).then((res) => {
        try {
          if (res.code == 0)
            resolve(this.buildSuccessResult<emptyData>(res));
          else
            resolve(this.buildFailedResult<emptyData>(res.message));
        } catch (e) {
          logger.error(e);
          resolve(this.buildExceptionResult<emptyData>(e));
        }
      });
    });
  }

  getMovies(keywords: string, index: number): Promise<returnModel<searchAnimeItem[]>> {
    return new Promise((resolve) => {
      let url = `https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=media_ft&page=${index}&order=&keyword=${keywords}&category_id=&__refresh__=true&highlight=1&single_column=0`;
      this.client.getResult(url).then((res) => {
        try {
          if (res.code == 0) {
            let arr: Array<searchAnimeItem> = res.data.data.result;
            resolve(this.buildSuccessResult<searchAnimeItem[]>(arr));
          } else
            resolve(this.buildFailedResult<searchAnimeItem[]>(res.message));
        } catch (e) {
          logger.error(e);
          resolve(this.buildExceptionResult<searchAnimeItem[]>(e));
        }
      });
    });
  }

  getBangumis(keywords: string, index: number): Promise<returnModel<searchAnimeItem[]>> {
    return new Promise((resolve) => {
      let url = `https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=media_bangumi&page=${index}&order=&keyword=${keywords}&category_id=&__refresh__=true&highlight=1&single_column=0`;
      this.client.getResult(url).then((res) => {
        try {
          if (res.code == 0) {
            let arr: Array<searchAnimeItem> = res.data.data.result;
            resolve(this.buildSuccessResult<searchAnimeItem[]>(arr));
          } else
            resolve(this.buildFailedResult<searchAnimeItem[]>(res.message));
        } catch (e) {
          logger.error(e);
          resolve(this.buildExceptionResult<searchAnimeItem[]>(e));
        }
      });
    });
  }

  getActivities(keywords: string, index: number): Promise<returnModel<searchTopicItem[]>> {
    return new Promise((resolve) => {
      let url = `https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=topic&page=${index}&order=&keyword=${keywords}&category_id=&__refresh__=true&highlight=1&single_column=0`;
      this.client.getResult(url).then((res) => {
        try {
          if (res.code == 0) {
            let arr: Array<searchTopicItem> = res.data.data.result;
            resolve(this.buildSuccessResult<searchTopicItem[]>(arr));
          } else
            resolve(this.buildFailedResult<searchTopicItem[]>(res.message));
        } catch (e) {
          logger.error(e);
          resolve(this.buildExceptionResult<searchTopicItem[]>(e));
        }
      });
    });
  }

  getUsers(keywords: string, order: string, type: string, index: number): Promise<returnModel<searchUserItem[]>> {
    return new Promise((resolve) => {
      let url = `https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=bili_user&page=${index}&keyword=${keywords}${order}${type}&__refresh__=true&changing=mid&highlight=1&single_column=0&category_id=`;
      this.client.getResult(url).then((res) => {
        try {
          if (res.code == 0) {
            let arr: Array<searchUserItem> = res.data.data.result;
            resolve(this.buildSuccessResult<searchUserItem[]>(arr));
          } else
            resolve(this.buildFailedResult<searchUserItem[]>(res.message));
        } catch (e) {
          logger.error(e);
          resolve(this.buildExceptionResult<searchUserItem[]>(e));
        }
      });
    });
  }

  getArticles(keywords: string, order: string, region: string, index: number): Promise<returnModel<searchArticleItem[]>> {
    return new Promise((resolve) => {
      let url = `https://api.bilibili.com/x/web-interface/search/type?context=&platform=pc&search_type=article&page=${index}&order=${order}&keyword=${keywords}&category_id=${region}&__refresh__=true&highlight=1&single_column=0`;
      this.client.getResult(url).then((res) => {
        try {
          if (res.code == 0) {
            let arr: Array<searchArticleItem> = res.data.data.result;
            resolve(this.buildSuccessResult<searchArticleItem[]>(arr));
          } else
            resolve(this.buildFailedResult<searchArticleItem[]>(res.message));
        } catch (e) {
          logger.error(e);
          resolve(this.buildExceptionResult<searchArticleItem[]>(e));
        }
      });
    });
  }

  getVideos(keywords: string, page: number, areaCondition: string, typeCondition: string): Promise<returnModel<searchVideoItem[]>> {
    return new Promise((resolve) => {
      let url = `https://api.bilibili.com/search?_device=android&appkey=${apiProvider.AndroidKey.appkey}&build=${apiProvider.Build5}&keyword=${keywords}&main_ver=v3&page=${page}&pagesize=20&platform=android&search_type=video&source_type=0${areaCondition}${typeCondition}`;
      this.client.getResult(url).then((res) => {
        try {
          if (res.code == 0) {
            let arr: Array<searchVideoItem> = res.data.result;
            resolve(this.buildSuccessResult<searchVideoItem[]>(arr));
          }  else
            resolve(this.buildFailedResult<searchVideoItem[]>(res.message));
        } catch (e) {
          logger.error(e);
          resolve(this.buildExceptionResult<searchVideoItem[]>(e));
        }
      });
    });
  }
}
export default new searchClient();